<template>
	<el-drawer
		:model-value="visible"
		title="写作"
		direction="rtl"
		size="100%"
		:before-close="onCancel"
		class="writing-drawer"
	>
		<div class="h-full px-4 py-2">
			<!-- 主容器 -->
			<div class="h-[calc(100vh-100px)] flex w-full">
				<!-- 左侧面板 - 文档编辑区域 -->
				<div class="w-[60%] min-w-[30%] overflow-auto transition-all duration-300 ease-in-out pr-3">
					<div class="h-full transition-shadow duration-200 border border-gray-200 rounded-lg shadow-sm hover:shadow-md">
						<!-- 卡片头部 -->
						<div class="flex items-center justify-between px-4 py-3 border-b border-gray-100 rounded-t-lg bg-gray-50">
							<span class="font-medium text-gray-700">文档编辑</span>
							<div class="flex items-center gap-2">
								<button
									v-if="documentContent && !isGenerating"
                  @click="onExport"
									class="flex items-center px-3 py-1 text-sm text-white transition-colors duration-200 rounded bg-primary hover:bg-primary-dark"
								>
									<svg xmlns="http://www.w3.org/2000/svg" class="w-4 h-4 mr-1" fill="none" viewBox="0 0 24 24" stroke="currentColor">
										<path
											stroke-linecap="round"
											stroke-linejoin="round"
											stroke-width="2"
											d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4"
										/>
									</svg>
									下载文档
								</button>
							</div>
						</div>

						<!-- 卡片内容 -->
						<div class="p-3 h-[calc(100%-55px)] overflow-auto">
							<div v-if="isGenerating" class="flex items-center justify-center h-full">
								<el-icon class="mr-2 text-xl is-loading text-primary"><Loading /></el-icon>
								<span class="text-gray-600">文档生成中...</span>
							</div>

							<!-- 文档编辑状态 -->
							<div v-else class="h-full">
                <ai-document-editor v-model:html="documentContent" v-model:model-name="form.modelName" ref="editorRef" class="document-editor h-[80%] overflow-hidden rounded" />

								
							</div>
						</div>
					</div>
				</div>

				<!-- 分割线 - 始终显示 -->
				<div class="w-[6px] bg-gray-100 hover:bg-gray-200 cursor-col-resize mx-1 relative group">
					<div class="absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 w-[2px] h-[30px] bg-gray-300 rounded group-hover:bg-gray-400"></div>
				</div>

				<!-- 右侧面板 - 写作配置 -->
				<div class="w-[40%] min-w-[30%] overflow-auto transition-all duration-300 ease-in-out pl-3">
					<div class="h-full transition-shadow duration-200 border border-gray-200 rounded-lg shadow-sm hover:shadow-md">
						<!-- 卡片头部 -->
						<div class="px-4 py-3 border-b border-gray-100 rounded-t-lg bg-gray-50">
							<div class="font-medium text-gray-700">写作配置</div>
						</div>

						<!-- 卡片内容 -->
						<div class="p-3 h-[calc(100%-55px)] overflow-auto">
							<el-form ref="formRef" :model="form" :rules="rules" label-width="80px" label-position="top" class="p-2">
								<!-- 基础信息表单 -->
								<div class="mb-6">
                <!-- AI模型配置 -->
								<div class="mb-6">
									<el-row :gutter="24" class="mb-4">
										<el-col :span="12" :xs="24" :sm="24" :md="12">
											选择模型：<ModelList ref="modelListComponent" :model-type="['Chat']" />
										</el-col>
									</el-row>
								</div>

									<el-row :gutter="24" class="mb-4">
										<el-col :span="24">
											<el-form-item label="主题/标题" prop="title">
												<el-input v-model="form.title" placeholder="例如：关于推进××城区老旧小区改造的实施意见" />
											</el-form-item>
										</el-col>
									</el-row>
									<el-row :gutter="24" class="mb-4">
										<el-col :span="24">
											<el-form-item label="参考资料" prop="abstractContent">
												<ai-editor
													v-model="form.abstractContent"
													:min-height="450"
													output="text"
													class="w-full"
													:disabled="isGenerating"
												/>
											</el-form-item>
										</el-col>
									</el-row>
								</div>

								<!-- 操作按钮 -->
								<div class="flex justify-center gap-3 mt-6 sm:justify-end">
                  <el-button @click="onCancel" :disabled="startLoading">取 消</el-button>

									<el-button
										:disabled="isGenerating"
                    @click="onStart"
										class="min-w-[100px] px-4 py-2 bg-primary text-white rounded-md hover:bg-primary-dark transition-colors duration-200 flex items-center justify-center disabled:opacity-50 disabled:cursor-not-allowed"
									>
										<svg
											v-if="isGenerating"
											class="w-4 h-4 mr-2 -ml-1 text-white animate-spin"
											xmlns="http://www.w3.org/2000/svg"
											fill="none"
											viewBox="0 0 24 24"
										>
											<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
											<path
												class="opacity-75"
												fill="currentColor"
												d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
											></path>
										</svg>
										<svg v-else xmlns="http://www.w3.org/2000/svg" class="w-4 h-4 mr-1" fill="none" viewBox="0 0 24 24" stroke="currentColor">
											<path
												stroke-linecap="round"
												stroke-linejoin="round"
												stroke-width="2"
												d="M9 13h6m-3-3v6m5 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"
											/>
										</svg>
										生 成
									</el-button>
								</div>
							</el-form>
						</div>
					</div>
				</div>
			</div>

          <!-- ============ 右上角悬浮进度卡片 ============ -->
      <teleport to="body">
        <div v-if="isWriting" class="fixed z-[9999] pointer-events-none" :style="cornerWrapStyle">
          <div class="pointer-events-auto rounded-2xl border bg-white shadow-xl px-4 py-3 flex items-center gap-3"
              style="width: 360px; max-width: 92vw; box-sizing: border-box; margin-top: 60%">
            <div class="flex-1 min-w-0">
              <div class="text-xs text-slate-500 mb-2 truncate">生成中… 已接收：{{ receivedChars }} 字符</div>
              <div class="h-2 w-full bg-slate-200 rounded overflow-hidden">
                <div class="h-full bg-slate-400 transition-all" :style="{ width: progressBarWidth }"></div>
              </div>
            </div>
            <el-button type="danger" size="small" @click="onStop">停止</el-button>
          </div>
        </div>
      </teleport>

		</div>
	</el-drawer>
</template>

<script setup lang="ts" name="WritingDrawer">
// ========== 导入声明 ==========
import { ElMessage, type FormRules } from 'element-plus';
import { Document, Loading } from '@element-plus/icons-vue';
import AiDocumentEditor from '/@/components/AiDocumentEditor/index.vue';
import ModelList from '/@/views/knowledge/aiChat/components/widgets/modelList.vue';
import AiEditor from '/@/components/AiEditor/index.vue';

import { downloadDocxFromHtml } from '/@/api/knowledge/html2Docx';
import other from '/@/utils/other';
import { Local } from '/@/utils/storage';


// ========== 响应式数据 ==========
const visible = ref(false)
const documentContent = ref<string>('');
const isGenerating = ref<boolean>(false);
const isWriting = ref(false)
const startLoading = ref(false)
const receivedChars = ref(0)
const editorRef = ref()
const form = reactive({
  title: '',
  abstractContent: '',
  modelName: '',
  docTemplateId: '',
  lockEditor: true,
})

const rules: FormRules = {
  title: [{ required: true, message: '请输入标题', trigger: 'blur' }],
}


// ========== 方法定义 ==========
function onCancel() {
	if (isWriting.value) { ElMessage.warning('正在生成中，先停止生成'); return }
	visible.value = false
}


/* ============ 开始/停止 写作 ============ */
let abortFn: null | (() => void) = null
let controller: AbortController | null = null

async function onStart() {
  if (!editorRef.value) { ElMessage.error('子组件未挂载'); return }
  startLoading.value = true

  try {
    await editorRef.value.waitForReady?.()
    if (!editorRef.value.generateDoc) { ElMessage.error('子组件未暴露 generateDoc'); return }

    editorRef.value.setHtml('')
    // 每次开始前，创建新的 AbortController（可选，但强烈建议）
    controller?.abort()
    controller = new AbortController()

    receivedChars.value = 0
    isWriting.value = true

    // ❗ 不要 await，在这里“先拿句柄，后等待”
    const task: any = editorRef.value.generateDoc({
      title: form.title,
      abstractContent: form.abstractContent,
      modelName: Local.get('selectedAiModel:Chat')?.name,
      docTemplateId: form.docTemplateId || undefined,
      lockEditor: form.lockEditor,
      htmlStream: true,

      onProgress: (_chunk: string, buffer: string) => {
        receivedChars.value = buffer.length
      }
    })

    // 1) 保存 abort（如果子组件返回）
    abortFn = task?.abort || null

    // 2) 等待完成（兼容两种返回约定：直接 Promise，或 {done:Promise}）
    const done: Promise<any> = task?.done ?? task

    done.then(() => {
      ElMessage.success('生成完成')
      isWriting.value = false
      abortFn = null
      controller = null
    }).catch((err: any) => {
      if (err?.name === 'AbortError') {
        ElMessage.info('已停止生成')
      } else {
        ElMessage.error(`生成失败：${err?.message || err}`)
      }
      isWriting.value = false
      abortFn = null
      controller = null
    })

  } catch (e: any) {
    ElMessage.error(e?.message || '启动生成失败')
    isWriting.value = false
  } finally {
    startLoading.value = false
  }
}

function onStop() {
  let stopped = false

  // 1) 优先调用 generateDoc 返回的 abort
  if (abortFn) {
    try { abortFn() } catch {}
    abortFn = null
    stopped = true
  }

  // 2) 次选：用我们自己的 AbortController
  if (controller && !stopped) {
    try { controller.abort() } catch {}
    controller = null
    stopped = true
  }

  if (stopped) {
    ElMessage.info('已请求停止生成')
    isWriting.value = false           // 立即关闭 UI，不用等回调
  } else {
    ElMessage.warning('当前任务不可中止或尚未开始')
  }
}

/* 导出 */
async function onExport() {
  const html = editorRef.value?.getHtml?.() || ''
  await downloadDocxFromHtml(html, '', other.adaptationUrl('/knowledge/ai-writer/convert/html-to-docx'))
}

/* 右上角进度条位置 */
const progressBarWidth = computed(() => {
  const max = 85
  const base = Math.min(max, Math.floor(receivedChars.value / 40))
  return `${base}%`
})
const cornerWrapStyle = computed(() => ({
  top: `max(12px, env(safe-area-inset-top))`,
  right: `max(16px, env(safe-area-inset-right))`,
}) as any)

const openWritingDrawer = (template: any) => {
  visible.value = true
  form.title = template.name
  form.docTemplateId = template.id
}

// 暴露方法给父组件
defineExpose({
  openWritingDrawer
})
</script>